From df3de397c7979af2fcc76df8536d9570b2f370dd Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Thu, 18 Aug 2005 17:04:48 +0000 Subject: [PATCH] Fix __get_user() and friends to work correctly for 64-bit quantities on x86/32. Should fix writable pagetables on PAE. Signed-off-by: Keir Fraser --- xen/arch/x86/mm.c | 4 ++-- xen/include/asm-x86/uaccess.h | 26 ++++++++++++-------------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 78270ee57c..70f58806c8 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -3299,8 +3299,8 @@ int ptwr_do_page_fault(struct domain *d, unsigned long addr, /* Finally, make the p.t. page writable by the guest OS. */ l1e_add_flags(pte, _PAGE_RW); - if ( unlikely(__copy_to_user(&linear_pg_table[l1_linear_offset(addr)], - &pte, sizeof(pte))) ) + if ( unlikely(__put_user(pte.l1, + &linear_pg_table[l1_linear_offset(addr)].l1)) ) { MEM_LOG("ptwr: Could not update pte at %p", (unsigned long *) &linear_pg_table[l1_linear_offset(addr)]); diff --git a/xen/include/asm-x86/uaccess.h b/xen/include/asm-x86/uaccess.h index e5e32d0938..b0bca22c7b 100644 --- a/xen/include/asm-x86/uaccess.h +++ b/xen/include/asm-x86/uaccess.h @@ -125,22 +125,20 @@ extern void __put_user_bad(void); __pu_err; \ }) -#define __get_user_nocheck(x,ptr,size) \ -({ \ - long __gu_err, __gu_val; \ - __get_user_size(__gu_val,(ptr),(size),__gu_err,-EFAULT);\ - (x) = (__typeof__(*(ptr)))__gu_val; \ - __gu_err; \ +#define __get_user_nocheck(x,ptr,size) \ +({ \ + long __gu_err; \ + __get_user_size((x),(ptr),(size),__gu_err,-EFAULT); \ + __gu_err; \ }) -#define __get_user_check(x,ptr,size) \ -({ \ - long __gu_err, __gu_val; \ - __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ - __get_user_size(__gu_val,__gu_addr,(size),__gu_err,-EFAULT); \ - (x) = (__typeof__(*(ptr)))__gu_val; \ - if (!__addr_ok(__gu_addr)) __gu_err = -EFAULT; \ - __gu_err; \ +#define __get_user_check(x,ptr,size) \ +({ \ + long __gu_err; \ + __typeof__(*(ptr)) __user *__gu_addr = (ptr); \ + __get_user_size((x),__gu_addr,(size),__gu_err,-EFAULT); \ + if (!__addr_ok(__gu_addr)) __gu_err = -EFAULT; \ + __gu_err; \ }) struct __large_struct { unsigned long buf[100]; }; -- 2.30.2